<!DOCTYPE html>
<html>
<head>
    <title>Energy Level Diagram</title>
</head>
<body>
<canvas id="physicsCanvas" width="550" height="400"></canvas>
<script>
    const canvas = document.getElementById("physicsCanvas");
    const ctx = canvas.getContext("2d");

    /**
     * Draws an arrowhead at a specific point and angle.
     * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
     * @param {number} x - The x-coordinate of the arrowhead's tip.
     * @param {number} y - The y-coordinate of the arrowhead's tip.
     * @param {number} angle - The angle of the arrow's direction in radians.
     * @param {number} headlen - The length of the arrowhead sides.
     */
    function drawArrowHead(ctx, x, y, angle, headlen = 12) {
        ctx.moveTo(x, y);
        ctx.lineTo(x - headlen * Math.cos(angle - Math.PI / 6), y - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(x, y);
        ctx.lineTo(x - headlen * Math.cos(angle + Math.PI / 6), y - headlen * Math.sin(angle + Math.PI / 6));
    }

    /**
     * Draws a straight arrow from a start point to an end point.
     * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
     * @param {number} fromx - The starting x-coordinate.
     * @param {number} fromy - The starting y-coordinate.
     * @param {number} tox - The ending x-coordinate.
     * @param {number} toy - The ending y-coordinate.
     */
    function drawArrow(ctx, fromx, fromy, tox, toy) {
        const angle = Math.atan2(toy - fromy, tox - fromx);
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        drawArrowHead(ctx, tox, toy, angle);
        ctx.stroke();
    }

    // --- Main Drawing ---
    
    // Set global styles to match the original image
    ctx.strokeStyle = "black";
    ctx.fillStyle = "black";
    ctx.lineWidth = 2.5;
    ctx.lineCap = "round";

    // --- 1. Draw Energy Levels ---
    // E1: Ground State
    ctx.beginPath();
    ctx.moveTo(50, 320);
    ctx.lineTo(450, 320);
    ctx.stroke();

    // E2: Metastable State
    ctx.beginPath();
    ctx.moveTo(280, 220);
    ctx.lineTo(450, 220);
    ctx.stroke();

    // E3: Pumping Band (drawn as a rectangle)
    ctx.beginPath();
    ctx.strokeRect(50, 80, 300, 40);

    // --- 2. Draw Transitions ---
    // Pumping transition (E1 -> E3)
    drawArrow(ctx, 100, 320, 100, 120);

    // Lasing transition (E2 -> E1)
    drawArrow(ctx, 350, 220, 350, 320);

    // Non-radiative decay (E3 -> E2), drawn as a wavy arrow
    ctx.beginPath();
    const nr_x1 = 250, nr_y1 = 120;
    const nr_x2 = 280, nr_y2 = 220;
    const p_prev_x = nr_x1 - 5, p_prev_y = nr_y1 + 70;
    ctx.moveTo(nr_x1, nr_y1);
    ctx.lineTo(nr_x1 + 10, nr_y1 + 40);
    ctx.lineTo(p_prev_x, p_prev_y);
    ctx.lineTo(nr_x2, nr_y2);
    const nr_angle = Math.atan2(nr_y2 - p_prev_y, nr_x2 - p_prev_x);
    drawArrowHead(ctx, nr_x2, nr_y2, nr_angle);
    ctx.stroke();

    // Emitted Photon (hv), drawn as a wavy arrow
    ctx.beginPath();
    const ph_x = 370, ph_y = 270;
    const ph_end_x = ph_x + 60;
    ctx.moveTo(ph_x, ph_y);
    ctx.lineTo(ph_x + 10, ph_y - 6);
    ctx.lineTo(ph_x + 20, ph_y + 6);
    ctx.lineTo(ph_x + 30, ph_y - 6);
    ctx.lineTo(ph_x + 40, ph_y + 6);
    ctx.lineTo(ph_x + 50, ph_y);
    ctx.lineTo(ph_end_x, ph_y);
    drawArrowHead(ctx, ph_end_x, ph_y, 0); // angle 0 for right-pointing horizontal arrow
    ctx.stroke();

    // --- 3. Add Labels ---
    // Helper for E_n labels with subscripts
    function drawEnergyLabel(ctx, x, y, n) {
        ctx.font = "bold 24px serif";
        ctx.fillText("E", x, y);
        ctx.font = "bold 18px serif";
        ctx.fillText(n, x + 13, y + 5);
    }
    
    // Position labels
    drawEnergyLabel(ctx, 370, 105, "3");
    drawEnergyLabel(ctx, 460, 225, "2");
    drawEnergyLabel(ctx, 460, 325, "1");

    // hv label
    ctx.font = "italic bold 22px serif";
    ctx.fillText("hν", 385, 260);

    // Figure caption
    ctx.font = "bold 24px serif";
    ctx.fillText("Fig. 3.1", 220, 370);

</script>
</body>
</html>